home *** CD-ROM | disk | FTP | other *** search
- { KAYPRO 4/83 INTERRUPT DRIVEN SERIAL I/O }
- { INTERFACE FOR TURBO PASCAL }
-
- { FRANK A. KURUCZ }
- { 2360 PASEO DE LAURA #20 }
- { OCEANSIDE CA, 92056 }
- { H- (619) 721-8530 }
- { W- (619) 433-6406 }
-
- { THIS PROGRAM INTERFACES WITH AN ASSEMBLY LANGUAGE PROGRAM }
- { SIOINT.ASM, TO PROVIDE BUFFERED SERIAL I/O }
-
- { THE PROGRAMMER HAS 3 PROCEDURES/FUNCTIONS AT HIS DISPOSITION: }
-
- { INITSIO - INITIALIZES SIO, SETS UP INTERRUPTS AND FIFOS }
- { WRITEBYTE - OUTPUTS A BYTE TO SERIAL OUTPUT }
- { READBYTE - IF ANY DATA PRESENT IN FIFO, IT IS RETURNED }
-
- { NOTE ************************************************************* }
-
- { WHEN COMPILING THE COM FILE MAKE SURE THAT THE END OF MEMORY }
- { PARAMETER IS SET BELOW THE INTERRUPT VECTOR }
- { OTHERWISE THE INTERRUPT PROCEDURES ARE AT RISK OF BEING OVERWRITTEN }
-
-
-
- {$A+}
- Const
-
- { ADDRESSES OF POINTERS, COUNTERS AND BUFFERS USED BY INTERRUPTS }
-
- VectorAddr = $E000; { INTERRUPT VECTOR }
-
- InSerialFifoAddr = $E100; { SERIAL INPUT FIFO }
- InFifoCountAddr = $E300; { FIFO COUNTER }
- InFifoInPtrAddr = $E301; { INPUT POINTER }
- InFifoOutPtrAddr = $E303; { OUTPUT POINTER }
-
- OutSerialFifoAddr = $E200; { SERIAL OUTPUT FIFO }
- OutFifoCountAddr = $E305; { FIFO COUNTER }
- OutFifoInPtrAddr = $E306; { INPUT POINTER }
- OutFifoOutPtrAddr = $E308; { OUTPUT POINTER }
-
- OutIntExpectedAddr = $E30A; { OUTPUT INTERRUPT ENABLED FLAG }
-
-
- { I/O PORT ADDRESSES }
-
- Control_Port_A = $06;
- Control_Port_B = $07;
- Baud_Port = $00;
- Data_Port_A = $04;
-
-
-
-
- { ######################################################################## }
- { ######################################################################## }
-
- { INITIALIZE THE SIO }
- { PARAMETERS }
-
- { BAUD: 0 = 50 8 = 1800 }
- { 1 = 75 9 = 2000 }
- { 2 = 110 10 = 2400 }
- { 3 = 134 11 = 3600 }
- { 4 = 150 12 = 4800 }
- { 5 = 300 13 = 7200 }
- { 6 = 600 14 = 9600 }
- { 7 = 1200 15 = 19200 }
-
- { DATASIZE: 5 = 5 DATA BITS }
- { 6 = 6 DATA BITS }
- { 7 = 7 DATA BITS }
- { 8 = 8 DATA BITS }
-
- { PARITY: 0 = NO PARITY }
- { 1 = ODD PARITY }
- { 2 = NO PARITY }
- { 3 = EVEN PARITY }
-
- { STOPBITS: 0 = ILLEGAL VALUE }
- { 1 = 1 STOP BIT }
- { 2 = 1.5 STOP BITS }
- { 3 = 2 STOP BITS }
-
-
- Procedure InitSIO(Baud,DataSize,Parity,StopBits:Integer);
-
- Var
- Vector: Byte;
-
-
- { INITIALIZE THE INPUT AND OUTPUT FIFOS AND COUNTERS AS WELL AS }
- { OUTPUT INTERRUPT EXPECTED FLAG }
-
- {1} Procedure InitFifos;
- Var
- InFifoCount: Byte Absolute InFifoCountAddr;
- InFifoInPtr: Integer Absolute InFifoInPtrAddr;
- InFifoOutPtr: Integer Absolute InFifoOutPtrAddr;
-
- OutFifoCount: Byte Absolute OutFifoCountAddr;
- OutFifoInPtr: Integer Absolute OutFifoInPtrAddr;
- OutFifoOutPtr: Integer Absolute OutFifoOutPtrAddr;
-
- OutIntExpected: Byte Absolute OutIntExpectedAddr;
-
-
- Begin
- InFifoCount:= 0;
- OutFifoCount:= 0;
-
- InFifoInPtr:= InSerialFifoAddr;
- InFifoOutPtr:= InSerialFifoAddr;
-
- OutFifoInPtr:= OutSerialFifoAddr;
- OutFifoOutPtr:= OutSerialFifoAddr;
-
- OutIntExpected:= 0;
- End;
-
-
- { NOW INITIALIZE THE SIO }
-
- Begin
-
- Inline($F3); { DISABLE INTERRUPTS }
-
- InitFifos; { SET UP FIFOS }
-
- { SET UP THE INTERRUPT VECTOR REGISTER TO THE MOST SIGNIFICANT }
- { BYTE OF THE INTERRUPT VECTOR ADDDRESS }
- { AND SET UP INTERRUPT MODE 2 }
-
- Vector:= VectorAddr Div $100;
- Inline($3A/Vector/ { LD A,(Vector) }
- $ED/$47/ { LD I,A }
- $ED/$5E); { IM 2 }
-
- { RESET THE SIO }
-
- Port[Control_Port_A]:=$18;
-
-
- { PROGRAM THE SIO FOR INTERRUPTS }
-
- Port[Control_Port_B]:= 2;
- Port[Control_Port_B]:= 0;
- Port[Control_Port_B]:= 1;
- Port[Control_Port_B]:= 4;
-
-
- { SET UP THE SERIAL CHARACTERISTICS OF PORT A }
- { CAUTION - PORT B IS USED FOR KEYBOARD DATA ENTRY }
- { SO DON'T MESS WITH IT }
-
- { MAKE SURE STOP BITS HAS A VALID VALUE }
-
- StopBits:=(StopBits Mod 4) Shl 2;
- If (StopBits = 0) Then Stopbits:=4;
-
- { MAKE SURE PARITY HAS A VALID VALUE AND PROGRAM IT }
- { ALONG WITH STOPBITS AND CLOCK MODE = 32X }
-
- Port[Control_Port_A]:=4;
- Port[Control_Port_A]:= $40 Or (Parity Mod 4) Or StopBits;
-
- { PROGRAM RECEIVE DATA BYTE SIZE }
-
- Case (DataSize) Of
- 5: DataSize:= 0;
- 6: DataSize:= $40;
- 7: DataSize:= $80;
- 8: DataSize:= $C0;
- Else
- DataSize:= $C0;
- End;
-
- { AND ENABLE RECEIVE }
-
- Port[Control_Port_A]:=3;
- Port[Control_Port_A]:=DataSize Or 1;
-
-
- { ALSO PROGRAM TRANSMIT DATA SIZE }
- { SETTING DTR AND CTS TO 1 AND ENABLING TRANSMISSION }
-
- Port[Control_Port_A]:=5;
- Port[Control_Port_A]:=$8A Or (DataSize Shr 1);
-
- { ENABLE TRANSMIT AND RECEIVE INTERRUPTS }
-
- Port[Control_Port_A]:=1;
- Port[Control_Port_A]:=$1B;
-
- { SET THE BAUD RATE, MAKING SURE THE PARAMETER IS VALID }
-
- Baud:=Baud Mod 16;
- Port[Baud_Port]:=Baud;
-
- Inline($FB); { RE-ENABLE INTERRUPTS }
- End;
-
-
-
-
- { ######################################################################### }
- { ######################################################################### }
-
- { WRITE A BYTE TO SERIAL OUTPUT }
-
- Procedure WriteByte(Data:Byte);
-
- Var
- OutFifoCount: Byte Absolute OutFifoCountAddr;
- OutFifoInPtr: Integer Absolute OutFifoInPtrAddr;
- OutFifoInPtrByte: Byte Absolute OutFifoInPtrAddr;
- OutIntExpected: Byte Absolute OutIntExpectedAddr;
-
- Begin
- { IF FIFO IS FULL WAIT FOR OUTPUT INTERRUPT TO MAKE ROOM }
-
- While (OutFifoCount = $FF) Do ;
-
- { DISABLE INTERRUPTS }
-
- Inline($F3);
-
- { ARE WE EXPECTING AN OUTPUT INTERRUPT ?}
-
- If (OutIntExpected <> 0) Then
- Begin
- { YES, INSERT DATA IN TO THE OUTPUT FIFO }
-
- { INCREMENT THE FIFO COUNT }
- OutFifoCount:= OutFifoCount + 1;
-
- { SAVE THE DATA IN THE FIFO }
- Mem[OutFifoInptr]:= Data;
-
- { INCREMENT THE FIFO POINTER }
- OutFifoInPtrByte:= OutFifoInPtrByte + 1;
- End
- Else
- Begin
- { OUTPUT INTERRUPTS HAVE BEEN SUSPENDED }
- { OUTPUT DATA AND RE-ENABLE THE INETRRUPT }
-
- Port[Data_Port_A]:= Data;
- OutIntExpected:=$FF;
- End;
-
- { RE-ENABLE INTERRUPTS }
-
- Inline($FB);
- End;
-
-
- { ######################################################################## }
- { ######################################################################## }
-
- { RETURNS A BYTE }
- { IF THERE IS DATA IN THE SERIAL INPUT FIFO THEN THE FUNCTION }
- { RETURNS THE FIRST BYTE IN THE FIFO AND NODATA = FALSE }
- { OTHERWISE A GARBAGE BYTE IS RETURNED AND NODATA = TRUE }
-
-
- Function ReadByte(Var NoData:Boolean):Byte;
- Var
- InFifoCount: Byte Absolute InFifoCountAddr;
- InFifoOutPtr: Integer Absolute InFifoOutPtrAddr;
- InFifoOutPtrByte: Byte Absolute InFifoOutPtrAddr;
-
- Data: Byte;
-
-
-
- Begin
- { DISABLE INTERRUPTS }
- Inline($F3);
-
- { IS THE FIFO EMPTY ? }
- If (InFifoCount <> 0) Then
- Begin
- { THERE IS DATA }
-
- { DECREMENT THE FIFO COUNTER }
- InFifoCount:= InFifoCount - 1;
-
- { GET THE DATA FROM THE FIFO }
- Data:= Mem[InFifoOutPtr];
-
- { INCREMENT THE FIFO POINTER WITH WRAP AROUND }
- InFifoOutPtrByte:= InFifoOutPtrByte+1;
-
- { LOWER NODATA FLAG }
- NoData:=False;
- End
- { IT IS EMPTY, RAISE THE NODATA FLAG }
- Else NoData:=True;
-
- { RE-ENABLE INTERRUPTS }
- Inline($FB);
-
- { RETURN THE BYTE }
- ReadByte:=Data;
- End;
-